unit bitcoin_common;

{$mode objfpc}{$H+}

interface
uses
  Classes, SysUtils, bitcoin_crypto;

const
  {$ifdef TESTNET}
  MAGIC_BYTES : array[0..3] of Byte = ($FA, $BF, $B5, $DA);
  {$else}
  MAGIC_BYTES : array[0..3] of Byte = ($F9, $BE, $B4, $D9);
  {$endif}

type
  Tp2pCommand = array[0..11] of Char;
  PCheckSum = ^TCheckSum;
  TCheckSum = array[0..3] of Byte;

{ the first 4 bytes of sha256(sha256()) this is used in many places }
function CheckSum(const Msg; MsgSize: SizeInt): TCheckSum;

procedure ReverseBuffer(const Buffer; Size: SizeInt);

{$note maybe move this to the bignum unit, this is only used after bignum to bin}
{ will add leading zeros to big endian Base256 string to reach total size }
function ZeroPadBin(S: String; Size: Integer): String;

implementation

procedure ReverseBuffer(const Buffer; Size: SizeInt);
var
  A, B : PByte;
  T    : Byte;
begin
  A := @Buffer;
  B := A + Size -1;
  while B > A do begin
    T  := A^;
    A^ := B^;
    B^ := T;
    Inc(A);
    Dec(B);
  end;
end;

function ZeroPadBin(S: String; Size: Integer): String;
var
  D, L : Integer;
begin
  L := Length(S);
  if L = Size then exit(S);
  Assert(L < Size);
  SetLength(Result, Size);
  D := Size - L;
  FillByte(Result[1], D, $00);
  Move(S[1], Result[1+D], L);
end;

function CheckSum(const Msg; MsgSize: SizeInt): TCheckSum;
var
  Digest : TSHA256Digest;
begin
  SHA256(Msg, MsgSize, Digest[1]);
  SHA256(Digest[1], 32, Digest[1]);
  Result := PCheckSum(@Digest[1])^;
end;



end.

